﻿using Caliburn.Micro;
using SS.WPF.Framework.Localization;
using SS.WPF.Framework.Restriction;
using SS.WPF.Framework.ValidationRule;

namespace SS.WPF.Framework.Markup
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Reflection;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Data;
    using System.Windows.Media;

    public static class Control
    {
        #region Content Attached Property

        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.RegisterAttached(
                "Content", typeof(string), typeof(Control), new PropertyMetadata(OnContentChanged));

        public static string GetContent(ContentControl control)
        {
            return (string)control.GetValue(ContentProperty);
        }

        public static void SetContent(ContentControl control, string value)
        {
            control.SetValue(ContentProperty, value);
        }

        private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var contentControl = d as ContentControl;
            if (contentControl == null)
            {
                return;
            }

            contentControl.DataContextChanged += ContentControlDataContextChanged;

            var path = e.NewValue as string;
            if (path == null)
            {
                return;
            }

            SetContentFromPath(contentControl, path);
        }

        private static void ContentControlDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var contentControl = sender as ContentControl;
            if (contentControl != null)
            {
                SetContentFromPath(contentControl, GetContent(contentControl));
            }
        }

        private static void SetContentFromPath(ContentControl contentControl, string path)
        {
            if (contentControl == null)
            {
                return;
            }

            var dataContext = contentControl.DataContext;
            if (dataContext == null)
            {
                return;
            }

            var type = path;
            var propertyInfo = dataContext.GetType().GetProperties().FirstOrDefault(x => x.Name == path);
            if (propertyInfo != null)
            {
                var customAttributes = propertyInfo.GetCustomAttributes(typeof(RestrictionAttribute), true);
                if (customAttributes.Length > 0)
                {
                    type = ((RestrictionAttribute)customAttributes[0]).Type;
                }
            }

            IRestriction value;

            var xmlSchemasService = IoC.Get<IRestrictionDictionary>();
            if (xmlSchemasService.TryGetValue(type, out value))
            {

            }

            if (value != null && value is IEnumRestriction)
            {
                var enumType = (IEnumRestriction)value;

                Array values = null;
                IEnumerable itemSource;
                if (propertyInfo != null && propertyInfo.PropertyType.IsEnum)
                {
                    var displays = Enum.GetValues(enumType.EnumType);
                    values = Enum.GetValues(propertyInfo.PropertyType);

                    IList<EnumPair> dictionary = new List<EnumPair>();
                    for (int index = 0; index < values.Length; index++)
                    {
                        var item = new EnumPair(displays.GetValue(index).ToString(), values.GetValue(index));
                        dictionary.Add(item);
                    }

                    itemSource = dictionary;
                }
                else
                {
                    values = Enum.GetValues(enumType.EnumType);
                    itemSource = (values.Cast<object>().ToDictionary(
                    val => IoC.Get<TranslationManager>().Translate(val.ToString()) as string, x => x));
                }

                if (propertyInfo == null || !propertyInfo.PropertyType.IsEnum)
                {
                    if (value is IntegerEnumRestriction)
                    {
                        itemSource = (values.Cast<object>().ToDictionary(
                            val => val.ToString(), x => (int)x));
                        // TranslationManager.Instance.Translate(val.ToString()) as string
                    }
                    else if (value is DoubleEnumRestriction)
                    {
                        itemSource = (values.Cast<object>().ToDictionary(val => val.ToString(), x => x.ToString()));
                    }
                    else if (value is StringEnumRestriction)
                    {
                        itemSource = ToDictionary(values);
                    }
                }



                ComboBox comboBox = BuildComboBox(contentControl, path, itemSource);
                contentControl.Content = comboBox;

                SetRestriction(comboBox, value);
                comboBox.SelectedIndex = 0;
            }
            else
            {
                if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool))
                {
                    var itemSource = new List<EnumPair>()
                    {
                        new EnumPair("No", false),
                        new EnumPair("Yes", true),
                    };

                    ComboBox comboBox = BuildComboBox(contentControl, path, itemSource);
                    contentControl.Content = comboBox;
                    SetRestriction(comboBox, value);
                }
                else
                {
                    var group = GetBindingGroup(contentControl);
                    var textBox = new TextBox();
                    var binding = new Binding(path)
                    {
                        Mode = BindingMode.TwoWay,
                        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                        ValidatesOnExceptions = true,
                        ValidatesOnDataErrors = true,
                        NotifyOnValidationError = true,
                        //NotifyOnTargetUpdated = true,
                        //NotifyOnSourceUpdated = true,
                        BindingGroupName = group
                    };
                    textBox.SetBinding(TextBox.TextProperty, binding);
                    SetRestriction(textBox, value);
                    contentControl.Content = textBox;
                }
            }


            contentControl.Focusable = false;
        }

        private static ComboBox BuildComboBox(ContentControl parent, string path, IEnumerable itemSource)
        {
            var comboBox = new ComboBox
            {
                ItemsSource = itemSource,
                DisplayMemberPath = "Key",
                SelectedValuePath = "Value"
            };

            var group = GetBindingGroup(parent);
            comboBox.SetBinding(Selector.SelectedValueProperty, new Binding(path)
            {
                Mode = BindingMode.TwoWay,
                UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
                ValidatesOnExceptions = true,
                ValidatesOnDataErrors = true,
                NotifyOnValidationError = true,
                //NotifyOnTargetUpdated = true,
                //NotifyOnSourceUpdated = true,
                BindingGroupName = group,
            });
            return comboBox;
        }

        #endregion

        #region Restriction Attached Property

        public static readonly DependencyProperty RestrictionProperty = DependencyProperty.RegisterAttached(
                "Restriction", typeof(IRestriction), typeof(Control), new PropertyMetadata(OnRestrictionChanged));

        /// <summary>
        /// Get instance of IRestriction applied for a control
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static IRestriction GetRestriction(DependencyObject control)
        {
            return (IRestriction)control.GetValue(RestrictionProperty);
        }

        public static void SetRestriction(DependencyObject control, IRestriction value)
        {
            control.SetValue(RestrictionProperty, value);
        }

        private static void OnRestrictionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var restriction = e.NewValue as IRestriction;
            if (restriction == null)
            {
                return;
            }

            var frameworkElement = d as FrameworkElement;
            if (frameworkElement != null)
            {
                frameworkElement.DataContextChanged +=
                    (sender, args) => SetValidationRules((DependencyObject)sender, restriction);
            }

            SetValidationRules(d, restriction);
        }

        private static void SetValidationRules(DependencyObject sender, IRestriction restriction)
        {
            Binding binding = GetBinding(sender);

            var textBox = sender as TextBox;
            if (textBox != null)
            {
                textBox.Loaded += OnTextBoxLoaded;
                textBox.TextChanged += TextBoxTextChanged;
                textBox.LostFocus += new RoutedEventHandler(textBox_LostFocus);
            }

            if (binding == null)
            {
                return;
            }

            if (restriction != null)
            {
                binding.ValidationRules.Add(new RestrictionValidationRule(restriction));
            }

            var validations = GetValidations(sender);
            if (validations != null)
            {
                foreach (var validationRule in validations)
                {
                    binding.ValidationRules.Add((ValidationRule)validationRule);
                }
            }
        }

        private static void OnTextBoxLoaded(object sender, RoutedEventArgs e)
        {
            var tb = (TextBox)sender;
            var binding2 = BindingOperations.GetBinding(tb, TextBox.TextProperty);
            var restriction = GetRestriction(tb);
            if (binding2 != null && restriction != null)
            {
                binding2.ValidationRules.Add(new RestrictionValidationRule(restriction));
            }

            var expression = tb.GetBindingExpression(TextBox.TextProperty);
            if (expression != null)
            {
                expression.UpdateSource();
            }
        }

        private static void TextBoxTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
        {
            var textBox = (TextBox)sender;
            var bindingExpression = BindingOperations.GetBindingExpression(textBox, TextBox.TextProperty);

            if (!textBox.IsLoaded)
            {
                return;
            }

            var binding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);

            var changes = textChangedEventArgs.Changes;
            var restriction = GetRestriction((DependencyObject)sender);
           if (bindingExpression != null)
            {
                if (restriction is IRestriction<double>
                           || restriction is IRestriction<float>)
                {
                    if (textBox.Text != null && Regex.IsMatch(textBox.Text, @"^0*\.0*$"))
                    {
                        return;
                    }
                }

                if (string.IsNullOrEmpty(textBox.Text) && !restriction.CanParse(textBox.Text))
                {
                    DirtyChecker.RaiseRecheckDirtyEvent(textBox);
                }
                else if (!restriction.CanParse(textBox.Text))
                {
                    if (!string.IsNullOrEmpty(textBox.Text))
                    {
                        if (Char.IsDigit(textBox.Text, 0))
                        {
                            var first = changes.First();
                            bindingExpression.UpdateTarget();
                            textBox.CaretIndex = first.Offset + 1;
                        }
                        else
                        {
                            textBox.Text = string.Empty;
                        }
                    }
                }
                else
                {
                    if (!bindingExpression.ValidateWithoutUpdate())
                    {
                        if (binding != null)
                        {
                            restriction.IsEnabled = false;

                            foreach (var validationRule in binding.ValidationRules.OfType<IValidationRuleCommon>())
                            {
                                (validationRule).IsEnabled = false;
                            }

                            bindingExpression.UpdateSource();

                            restriction.IsEnabled = true;
                            foreach (var validationRule in binding.ValidationRules.OfType<IValidationRuleCommon>())
                            {
                                (validationRule).IsEnabled = true;
                            }

                            bindingExpression.UpdateSource();
                        }
                    }
                }
            }
        }

        private static void textBox_LostFocus(object sender, RoutedEventArgs e)
        {
            var textBox = (TextBox)sender;
            var bindingExpression = BindingOperations.GetBindingExpression(textBox, TextBox.TextProperty);

            if (!textBox.IsLoaded)
            {
                return;
            }

            var binding = BindingOperations.GetBinding(textBox, TextBox.TextProperty);

            var restriction = GetRestriction((DependencyObject)sender);
            if (bindingExpression != null)
            {
                if (string.IsNullOrEmpty(textBox.Text) && !restriction.CanParse(textBox.Text))
                {
                    if (restriction is IRestriction<int>
                        || restriction is IRestriction<ulong>
                        || restriction is IRestriction<double>
                        || restriction is IRestriction<float>)
                    {
                        if (textBox.IsLoaded)
                        {
                            //textBox.Text = "0";
                            if (binding != null && textBox.Text != "")
                            {
                                restriction.IsEnabled = false;
                                bindingExpression.UpdateSource();
                                restriction.IsEnabled = true;
                                bindingExpression.UpdateSource();
                            }
                        }
                    }
                }
            }
        }

        #endregion

        #region Description Attached Property

        public static readonly DependencyProperty DescriptionProperty =
            DependencyProperty.RegisterAttached(
                "Description", typeof (object), typeof (Control),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, OnDescriptionChanged));

        public static string GetDescription(DependencyObject control)
        {
            return (string)control.GetValue(DescriptionProperty);
        }

        public static void SetDescription(DependencyObject control, string value)
        {
            control.SetValue(DescriptionProperty, value);
        }

        private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        #endregion

        #region HandleError Attached Property

        public static readonly DependencyProperty HandleErrorProperty =
            DependencyProperty.RegisterAttached(
                "HandleError", typeof(bool), typeof(Control), new PropertyMetadata(OnHandleErrorChanged));

        public static bool GetHandleError(DependencyObject control)
        {
            return (bool)control.GetValue(HandleErrorProperty);
        }

        public static void SetHandleError(DependencyObject control, bool value)
        {
            control.SetValue(HandleErrorProperty, value);
        }

        private static void OnHandleErrorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var frameworkElement = d as FrameworkElement;
            if (frameworkElement == null)
            {
                return;
            }
            if ((bool)e.NewValue)
            {
                frameworkElement.AddHandler(Validation.ErrorEvent, new EventHandler<ValidationErrorEventArgs>(OnValidationError));
                frameworkElement.AddHandler(TextBoxBase.TextChangedEvent, new RoutedEventHandler(HandleTextChanged));
                frameworkElement.AddHandler(Selector.SelectionChangedEvent, new RoutedEventHandler(HandleSelectionChanged));
            }
        }

        private static void HandleSelectionChanged(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource is ComboBox)
            {
                DetectError(sender);
            }
        }

        private static void HandleTextChanged(object sender, RoutedEventArgs e)
        {
            DetectError(sender);
        }

        private static void OnValidationError(object sender, ValidationErrorEventArgs e)
        {
            DetectError(sender);
        }

        private static void DetectError(object sender)
        {
            var dependencyObject = (DependencyObject)sender;
            var hasError = DetectError(dependencyObject);
            SetHasError(dependencyObject, hasError);
        }

        public static bool DetectError(DependencyObject dependencyObject)
        {
            if (Validation.GetHasError(dependencyObject))
            {
                return true;
            }

            var count = VisualTreeHelper.GetChildrenCount(dependencyObject);
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(dependencyObject, i);
                if (DetectError(child))
                {
                    return true;
                }
            }

            return false;
        }

        #endregion

        #region HasError Attached Property

        public static readonly DependencyProperty HasErrorProperty =
            DependencyProperty.RegisterAttached(
                "HasError", typeof(bool), typeof(Control), new PropertyMetadata(false, OnHasErrorChanged));

        public static bool GetHasError(DependencyObject control)
        {
            return (bool)control.GetValue(HasErrorProperty);
        }

        public static void SetHasError(DependencyObject control, bool value)
        {
            control.SetValue(HasErrorProperty, value);
        }

        private static void OnHasErrorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion

        #region NoneDescription Attached Property

        public static readonly DependencyProperty NoneDescriptionProperty =
            DependencyProperty.RegisterAttached(
                "NoneDescription", typeof(bool), typeof(Control), new PropertyMetadata(OnNoneDescriptionChanged));

        public static bool GetNoneDescription(DependencyObject control)
        {
            return (bool)control.GetValue(NoneDescriptionProperty);
        }

        public static void SetNoneDescription(DependencyObject control, bool value)
        {
            control.SetValue(NoneDescriptionProperty, value);
        }

        private static void OnNoneDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion

        #region BindingGroup Attached Property

        public static readonly DependencyProperty BindingGroupProperty =
            DependencyProperty.RegisterAttached(
                "BindingGroup", typeof(string), typeof(Control), new PropertyMetadata(OnBindingGroupChanged));

        public static string GetBindingGroup(DependencyObject control)
        {
            return (string)control.GetValue(BindingGroupProperty);
        }

        public static void SetBindingGroup(DependencyObject control, string value)
        {
            control.SetValue(BindingGroupProperty, value);
        }

        private static void OnBindingGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion

        #region Validations Attached Property

        public static readonly DependencyProperty ValidationsProperty =
            DependencyProperty.RegisterAttached(
                "Validations", typeof(IEnumerable), typeof(Control), new FrameworkPropertyMetadata(null,
                    FrameworkPropertyMetadataOptions.Inherits, OnValidationsChanged));

        public static IEnumerable GetValidations(DependencyObject control)
        {
            return (IEnumerable)control.GetValue(ValidationsProperty);
        }

        public static void SetValidations(DependencyObject control, IEnumerable value)
        {
            control.SetValue(ValidationsProperty, value);
        }

        private static void OnValidationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var olds = e.NewValue as IEnumerable;
            var binding = GetBinding(d);
            if (binding == null)
            {
                return;
            }

            if (olds != null)
            {
                foreach (var old in olds.OfType<ValidationRule>())
                {
                    binding.ValidationRules.Remove(old);
                }
            }

            var enums = e.NewValue as IEnumerable;
            if (enums != null)
            {
                foreach (var rule in enums.OfType<ValidationRule>())
                {
                    binding.ValidationRules.Add(rule);
                }
            }
        }

        #endregion

        #region Key Attached Property

        public static readonly DependencyProperty KeyProperty =
           DependencyProperty.RegisterAttached(
               "Key", typeof(string), typeof(Control), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, OnKeyChanged));

        public static string GetKey(DependencyObject control)
        {
            return (string)control.GetValue(KeyProperty);
        }

        public static void SetKey(DependencyObject control, string value)
        {
            control.SetValue(KeyProperty, value);
        }

        private static void OnKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion

        #region Name Attached Property

        public static readonly DependencyProperty NameProperty =
           DependencyProperty.RegisterAttached(
               "Name", typeof(string), typeof(Control), new FrameworkPropertyMetadata(null,
                   FrameworkPropertyMetadataOptions.Inherits, OnNameChanged));

        public static string GetName(DependencyObject control)
        {
            return (string)control.GetValue(NameProperty);
        }

        public static void SetName(DependencyObject control, string value)
        {
            control.SetValue(NameProperty, value);
        }

        private static void OnNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }

        #endregion

        #region Public Methods

        public static Binding GetBinding(DependencyObject sender)
        {
            Binding binding = null;
            if (sender is TextBox)
            {
                binding = BindingOperations.GetBinding(sender, TextBox.TextProperty);
            }
            else if (sender is Selector)
            {

                binding = BindingOperations.GetBinding(sender, Selector.SelectedValueProperty);
            }
            else if (sender is ContentControl)
            {
                return GetBinding(((ContentControl)sender).Content as DependencyObject);
            }

            return binding;
        }

        public static DependencyProperty GetDependencyProperty(DependencyObject sender)
        {
            DependencyProperty dependencyProperty = null;
            if (sender is TextBox)
            {
                dependencyProperty = TextBox.TextProperty;
            }
            else if (sender is Selector)
            {
                dependencyProperty = Selector.SelectedValueProperty;
            }
            else if (sender is ContentControl)
            {
                return GetDependencyProperty(((ContentControl)sender).Content as DependencyObject);
            }

            return dependencyProperty;
        }

        public static BindingExpression GetBindingExpression(DependencyObject sender)
        {
            BindingExpression binding = null;
            if (sender is TextBox)
            {
                binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
            }
            else if (sender is Selector)
            {
                binding = ((Selector)sender).GetBindingExpression(Selector.SelectedValueProperty);
            }
            else if (sender is ContentControl)
            {
                var dependencyObject = ((ContentControl)sender).Content as DependencyObject;
                if (dependencyObject != null)
                {
                    return GetBindingExpression(dependencyObject);
                }
            }

            return binding;
        }

        public static IEnumerable ToDictionary(IEnumerable enums)
        {
            return (enums.Cast<object>().Select(item => new EnumPair(item.ToString(), item.ToString()))).ToList();
        }

        public static T GetValue<T>(BindingExpression expression, object dataItem)
        {
            if (expression == null || dataItem == null)
            {
                return default(T);
            }

            string bindingPath = expression.ParentBinding.Path.Path;
            string[] pathParts = bindingPath.Split('.');

            object currentObject = dataItem;
            Type currentType = null;

            for (int i = 0; i < pathParts.Length; i++)
            {
                currentType = currentObject.GetType();
                PropertyInfo property = currentType.GetProperty(pathParts[i]);
                if (property == null)
                {
                    currentObject = null;
                    break;
                }
                currentObject = property.GetValue(currentObject, null);
                if (currentObject == null)
                {
                    break;
                }
            }

            return (T)currentObject;
        }

        #endregion
    }

    [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
    public class RestrictionAttribute : Attribute
    {
        // This is a positional argument
        public RestrictionAttribute(string type)
        {
            this.Type = type;
        }

        public string Type { get; private set; }
    }

    public class EnumPair : INotifyPropertyChanged, IEquatable<EnumPair>, IDisposable, IWeakEventListener
    {
        private readonly string _key;

        public event PropertyChangedEventHandler PropertyChanged;

        public EnumPair(string key, object value)
        {
            this._key = key;
            this.Value = value;
            LanguageChangedEventManager.AddListener(IoC.Get<TranslationManager>(), this);
        }

        public string Key
        {
            get
            {
                return IoC.Get<TranslationManager>().Translate(_key) as string;
            }
        }

        ~EnumPair()
        {
            Dispose(false);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                Debug.WriteLine("Disposing");
                // Code to dispose the managed resources of the class
                LanguageChangedEventManager.RemoveListener(IoC.Get<TranslationManager>(), this);
            }
            // Code to dispose the un-managed resources of the class
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public object Value { get; set; }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            return obj.GetType() == typeof(EnumPair) && Equals((EnumPair)obj);
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <returns>
        /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public bool Equals(EnumPair other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }
            return ReferenceEquals(this, other) || Equals(other.Value, this.Value);
        }

        /// <summary>
        /// Serves as a hash function for a particular type. 
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        public override int GetHashCode()
        {
            return (this.Value != null ? this.Value.GetHashCode() : 0);
        }

        public static bool operator ==(EnumPair left, EnumPair right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(EnumPair left, EnumPair right)
        {
            return !Equals(left, right);
        }

        #region Implementation of IWeakEventListener

        /// <summary>
        /// Receives events from the centralized event manager.
        /// </summary>
        /// <returns>
        /// true if the listener handled the event. It is considered an error by the <see cref="T:System.Windows.WeakEventManager"/> handling in WPF to register a listener for an event that the listener does not handle. Regardless, the method should return false if it receives an event that it does not recognize or handle.
        /// </returns>
        /// <param name="managerType">The type of the <see cref="T:System.Windows.WeakEventManager"/> calling this method.</param><param name="sender">Object that originated the event.</param><param name="e">Event data.</param>
        public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
        {
            if (managerType == typeof(LanguageChangedEventManager))
            {
                OnLanguageChanged(sender, e);
                return true;
            }
            return false;
        }

        void OnLanguageChanged(object sender, EventArgs e)
        {
            this.NotifyOfPropertyChange("Key");
        }

        private void NotifyOfPropertyChange(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        #endregion
    }
}